package com.lswms.modules.lswms.service.impl.orders;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lswms.common.page.PageData;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.common.utils.Result;
import com.lswms.modules.lswms.Constant.OrderConstant;
import com.lswms.modules.lswms.Constant.ReceiptConstant;
import com.lswms.modules.lswms.Constant.TaskConstant;
import com.lswms.modules.lswms.dao.base.SkuDao;
import com.lswms.modules.lswms.dao.base.ZoneDao;
import com.lswms.modules.lswms.dao.orders.OrderdetailDao;
import com.lswms.modules.lswms.dao.orders.OrderdetaillistDao;
import com.lswms.modules.lswms.dao.orders.OrdersDao;
import com.lswms.modules.lswms.dao.stock.InventoryDao;
import com.lswms.modules.lswms.dao.task.TaskDao;
import com.lswms.modules.lswms.dto.orders.OrdersDTO;
import com.lswms.modules.lswms.entity.base.SkuEntity;
import com.lswms.modules.lswms.entity.base.ZoneEntity;
import com.lswms.modules.lswms.entity.orders.OrderdetailEntity;
import com.lswms.modules.lswms.entity.orders.OrderdetaillistEntity;
import com.lswms.modules.lswms.entity.orders.OrdersEntity;
import com.lswms.modules.lswms.entity.stock.InventoryEntity;
import com.lswms.modules.lswms.entity.task.TaskEntity;
import com.lswms.modules.lswms.service.base.SequenceService;
import com.lswms.modules.lswms.service.orders.OrderdetailService;
import com.lswms.modules.lswms.service.orders.OrdersService;

/**
 * 出库
 *
 * @author DX sunlightcs@gmail.com
 * @since 1.0.0 2021-06-24
 */
@Service
public class OrdersServiceImpl extends CrudServiceImpl<OrdersDao, OrdersEntity, OrdersDTO> implements OrdersService {

	@Autowired
	private OrderdetailDao orderdetailDao;

	@Autowired
	private OrderdetaillistDao orderdetaillistDao;

	@Autowired
	private TaskDao taskDao;

	@Autowired
	private OrdersDao ordersDao;

	@Autowired
	private InventoryDao inventoryDao;

	@Autowired
	private SkuDao skuDao;

	@Autowired
	private ZoneDao zoneDao;

	@Autowired
	SequenceService sequenceService;

	@Autowired
	private OrderdetailService orderdetailService;

	@Override
	public QueryWrapper<OrdersEntity> getWrapper(Map<String, Object> params) {
		String id = (String) params.get("id");
		String orderkey = (String) params.get("orderkey");
		String type = (String) params.get("type");
		String status = (String) params.get("status");
		String recipientId = (String) params.get("recipientId");
		String recipient = (String) params.get("recipient");

		QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
		wrapper.eq(StringUtils.isNotBlank(id), "id", id);
		wrapper.eq(StringUtils.isNotBlank(orderkey), "orderkey", orderkey);
		wrapper.eq(StringUtils.isNotBlank(type), "type", type);
		wrapper.eq(StringUtils.isNotBlank(status), "status", status);
		wrapper.eq(StringUtils.isNotBlank(recipientId), "recipientId", recipientId);
		wrapper.like(StringUtils.isNotBlank(recipient), "recipient", recipient);

		wrapper.orderByDesc("orderkey");

		return wrapper;
	}

	@Override
	public PageData<OrdersEntity> pageBySql(Map<String, Object> params) {
		IPage<OrdersEntity> page = baseDao.selectPageBySql(getPage(params, null, false), getWrapper(params));
		return getPageData(page, OrdersEntity.class);
	}

	@Override
	public OrdersEntity selectByOrderkey(String orderkey) {
		QueryWrapper<OrdersEntity> query = new QueryWrapper<OrdersEntity>();
		query.eq("orderkey", orderkey);

		return baseDao.selectOne(query);
	}

	@Override
	public String valide(OrdersDTO dto) {
		// 获取订单信息
		String orderkey = dto.getOrderkey();
		Integer oldStatus = dto.getStatus();

		String oldType = dto.getType();
		// 查询订单信息
		QueryWrapper<OrdersEntity> orderQuery = new QueryWrapper<OrdersEntity>();

		orderQuery.eq("orderkey", orderkey);
		OrdersEntity ordersEntity = baseDao.selectOne(orderQuery);
		if (ordersEntity != null) {

			Integer newStatus = ordersEntity.getStatus();
			if (oldStatus != newStatus) {
				return "单据状态已变更,请重试";
			}

			String newType = ordersEntity.getType();
			if (newStatus > OrderConstant.ORDERSTATUS_0 && !oldType.equals(newType)) {
				return "非新建的订单不允许更改单据类型";
			}
		}
		if (StringUtils.isBlank(oldType)) {
			return "请选择订单类型";
		}

		return null;
	}

	@Override
	public String valideDelete(Long[] ids) {
		QueryWrapper<OrdersEntity> orderQuery = new QueryWrapper<OrdersEntity>();
		orderQuery.in("id", ids);
		orderQuery.ne("status", OrderConstant.ORDERSTATUS_0);

		Integer count = baseDao.selectCount(orderQuery);
		if (count > 0) {
			return "不允许删除非新建的订单";
		}

		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Result putClose(List<OrdersEntity> list) {
		List<String> orderkeyList = new ArrayList<String>();
		for (OrdersEntity ordersEntity : list) {
			orderkeyList.add(ordersEntity.getOrderkey());
		}

		if (orderkeyList.size() == 0) {
			return new Result();
		}

		QueryWrapper<OrderdetaillistEntity> orderdetailListEntityQueryWrapper = new QueryWrapper<OrderdetaillistEntity>();
		orderdetailListEntityQueryWrapper.in("orderkey", orderkeyList);
		orderdetailListEntityQueryWrapper.lt("status", OrderConstant.ORDERSTATUS_21);
		Integer count = orderdetaillistDao.selectCount(orderdetailListEntityQueryWrapper);
		if (count > 0) {
			return new Result().error("出货单存在未发货的拣货明细，操作失败");
		}

		UpdateWrapper<OrderdetailEntity> updateOrderdetailWrapper = new UpdateWrapper<>();
		updateOrderdetailWrapper.in("orderkey", orderkeyList);
		updateOrderdetailWrapper.set("diffqty", 0);
		updateOrderdetailWrapper.set("status", OrderConstant.ORDERSTATUS_25);
		orderdetailDao.update(null, updateOrderdetailWrapper);

		UpdateWrapper<OrdersEntity> updateOrdersWrapper = new UpdateWrapper<>();
		updateOrdersWrapper.in("orderkey", orderkeyList);
		updateOrdersWrapper.set("status", OrderConstant.ORDERSTATUS_25);
		ordersDao.update(null, updateOrdersWrapper);
		return new Result();
	}

	@Transactional(rollbackFor = Exception.class)
	public Result putClose(OrderdetailEntity orderdetailEntity) {
		QueryWrapper<OrderdetaillistEntity> orderdetaillistEntityQueryWrapper = new QueryWrapper<>();
		orderdetaillistEntityQueryWrapper.eq("orderkey", orderdetailEntity.getOrderkey());
		orderdetaillistEntityQueryWrapper.eq("line", orderdetailEntity.getLine());
		List<OrderdetaillistEntity> orderdetaillistEntities = orderdetaillistDao
				.selectList(orderdetaillistEntityQueryWrapper);
		for (OrderdetaillistEntity orderdetaillistEntity : orderdetaillistEntities) {
			Integer status = orderdetaillistEntity.getStatus();
			if (status != OrderConstant.ORDERSTATUS_21) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return new Result().error("有出货单明细并未收货");
			}
			UpdateWrapper<OrderdetaillistEntity> updateWrapper = new UpdateWrapper<>();
			updateWrapper.eq("orderkey", orderdetaillistEntity.getOrderkey());
			updateWrapper.eq("line", orderdetaillistEntity.getLine());
			updateWrapper.eq("linelist", orderdetaillistEntity.getLinelist());
			updateWrapper.set("status", OrderConstant.ORDERSTATUS_25);
			orderdetaillistDao.update(null, updateWrapper);
			QueryWrapper<TaskEntity> taskEntityQueryWrapper = new QueryWrapper<>();
			taskEntityQueryWrapper.eq("sku", orderdetaillistEntity.getSku());
			taskEntityQueryWrapper.eq("tolocation", orderdetaillistEntity.getToloc());
			taskEntityQueryWrapper.eq("totray", orderdetaillistEntity.getTotray());
			taskEntityQueryWrapper.eq("tobox", orderdetaillistEntity.getTobox());
			taskEntityQueryWrapper.eq("tolot", orderdetaillistEntity.getLot());
			List<TaskEntity> taskEntities = taskDao.selectList(taskEntityQueryWrapper);
			for (TaskEntity taskEntity : taskEntities) {
				if (taskEntity.getStatus() == TaskConstant.TASK_0) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return new Result().error("有下发任务未完成，不可关单");
				}
			}

		}
		return new Result();
	}

	@Override
	public Result checkStatus(String orderkey) {
		QueryWrapper<OrdersEntity> ordersEntityQueryWrapper = new QueryWrapper<>();
		ordersEntityQueryWrapper.eq("orderkey", orderkey);
		OrdersEntity ordersEntity = ordersDao.selectOne(ordersEntityQueryWrapper);
		if (ordersEntity.getStatus() == OrderConstant.ORDERSTATUS_25) {
			return new Result().error("订单已关闭，无法操作");
		}

		return new Result();
	}

	@Override
	public String qcCreate(Map map) {
		if (map == null) {
			return "请输入二维码信息";
		}
		String qc = (String) map.get("QC");
		if (StringUtils.isBlank(qc)) {
			return "请输入二维码信息";
		}

		String[] qcs = qc.split(";");
		if (qcs.length == 0) {
			return "二维码格式不对,不能生成入库单";
		}
		String planNo = qcs[0];
//		String taskNo = qcs[1];
//		String skuNo = qcs[2];
//		String preqtyStr = qcs[3];
//		String luNo = qcs[4];
//		String cailiaoNo = qcs[5];
//		String paiNo = qcs[6];
//		String skuName = qcs[7];

		if (StringUtils.isBlank(planNo)) {
			return "二维码中的计划单号为空,不能生成入库单";
		}

		// 查询计划单号的库存记录
		List<Map<String, Object>> list = inventoryDao.selectByPlanNo(planNo);
		if (list.size() == 0) {
			return "二维码中的计划单号没有有效库存,不能生成出库单";
		}

		String orderkey = (String) map.get("orderkey");
		if (StringUtils.isBlank(orderkey)) {
			// 增加主表
			orderkey = sequenceService.getSequence("order");
			OrdersEntity ordersEntity = new OrdersEntity();
			ordersEntity.setOrderkey(orderkey);
			ordersEntity.setStatus(OrderConstant.ORDERSTATUS_0);
			ordersEntity.setSourcekey(planNo);
			ordersEntity.setType("XS");
			baseDao.insert(ordersEntity);
		}
		// 增加明细
		for (Map<String, Object> map2 : list) {
			String sku = (String) map2.get("sku");
			BigDecimal qty = (BigDecimal) map2.get("qty");

			// 查询物料的相关信息
			QueryWrapper<SkuEntity> querySku = new QueryWrapper<SkuEntity>();
			querySku.eq("sku", sku);
			SkuEntity skuEntity = skuDao.selectOne(querySku);

			OrderdetailEntity orderdetailEntity = new OrderdetailEntity();
			orderdetailEntity.setOrderkey(orderkey);
			Integer count = orderdetailService.getOrderdetailLine(orderkey);
			if (count == null) {
				count = 1;
			}
			orderdetailEntity.setLine(count + 1);
			orderdetailEntity.setSku(skuEntity.getSku());
			orderdetailEntity.setStatus(ReceiptConstant.RECEIPTSTATUS_0);
			orderdetailEntity.setQty(qty);
			orderdetailEntity.setDiffqty(qty);
			orderdetailEntity.setLot3(StringUtils.EMPTY);
			orderdetailEntity.setLot4(StringUtils.EMPTY);
			orderdetailEntity.setLot5(StringUtils.EMPTY);
			orderdetailEntity.setLot6(planNo);
			orderdetailEntity.setLot7(StringUtils.EMPTY);
			orderdetailEntity.setLot8(StringUtils.EMPTY);
			orderdetailEntity.setLot9(StringUtils.EMPTY);
			orderdetailEntity.setLot10(StringUtils.EMPTY);
			orderdetailEntity.setLot11(StringUtils.EMPTY);
			orderdetailEntity.setLot12(StringUtils.EMPTY);
			orderdetailEntity.setLot13(StringUtils.EMPTY);
			orderdetailEntity.setLot14(StringUtils.EMPTY);
			orderdetailEntity.setLot15(StringUtils.EMPTY);
			orderdetailEntity.setAllocationstrategy(skuEntity.getAllocationstrategy());
			orderdetailEntity.setRolateby(skuEntity.getRolateby());
			orderdetailEntity.setUnit(skuEntity.getUnit());
			orderdetailDao.insert(orderdetailEntity);
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String orderEmptyLPN(Map<String, Object> params, String remoteAddr) {
		String zone = (String) params.get("zone");
		String count = (String) params.get("count");

		// 校验区是否存在
		QueryWrapper<ZoneEntity> zoneQuery = new QueryWrapper<ZoneEntity>();
		zoneQuery.eq("zonecode", zone);
		Integer zonecount = zoneDao.selectCount(zoneQuery);
		if (zonecount == null && zonecount == 0) {
			return "请输入有效的区编码";
		}
		//校验数字
		BigDecimal countB = BigDecimal.ZERO;
		try {
			countB = new BigDecimal(count);
		} catch (Exception e) {
			return "请输入有效的数量";
		}
		
		if(countB.compareTo(BigDecimal.ZERO) <=0) {
			return  "请输入有效的数量";
		}
		
		//查询所选区域的库存记录
		QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
		inventoryQuery.eq("sku", "KX");
		inventoryQuery.exists("select 1 from lswms_location where lswms_inventory.location = lswms_location.location and lswms_location.zonecode = '"+zone+"' ");
		inventoryQuery.notExists("select 1 from lswms_task where lswms_task.fromtray = lswms_inventory.tray and lswms_task.status<9");
		inventoryQuery.notExists("select 1 from lswms_task where lswms_task.totray = lswms_inventory.tray and lswms_task.status<9");
		List<InventoryEntity> list = inventoryDao.selectList(inventoryQuery);
		if(list.size()==0) {
			return "区："+zone+"没有空托盘，请选择其他区";
		}
		
		// 增加空托盘移库任务
		for(int i = 0; i< list.size() && i< countB.intValue() ;i++) {
			InventoryEntity inventoryEntity= list.get(i);		
			String taskkey = sequenceService.getSequence("task");

			TaskEntity taskEntityAdd = new TaskEntity();
			taskEntityAdd.setTaskkey(taskkey);
			taskEntityAdd.setTasktype(TaskConstant.TASK_MV);
			taskEntityAdd.setPriority(0);
			taskEntityAdd.setStatus(TaskConstant.TASK_0);
			taskEntityAdd.setSku(inventoryEntity.getSku());
			taskEntityAdd.setQty(inventoryEntity.getQty());
			taskEntityAdd.setFromlocation(inventoryEntity.getLocation());
			taskEntityAdd.setTolocation("PICK");
			taskEntityAdd.setFromtray(inventoryEntity.getTray());
			taskEntityAdd.setTotray(inventoryEntity.getTray());
			taskEntityAdd.setFrombox(inventoryEntity.getBox());
			taskEntityAdd.setTobox(inventoryEntity.getBox());
			taskEntityAdd.setFromlot(inventoryEntity.getLot());
			taskEntityAdd.setTolot(inventoryEntity.getLot());
			taskEntityAdd.setIp(remoteAddr);
			taskDao.insert(taskEntityAdd);
		}
		
		return null;
	}

}
